﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WF.VecDraw.Dialog;
using Gencode.VECore;
using Gencode.VECUtil;

namespace WF.VecDraw
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainGui : Window
    {
		ToolsWindow tools;
        LayerDialog layers;
        FileManager docManager;

        public MainGui()
        {
            InitializeComponent();

			InitializeToolProperties();
        }

		private void ShowToolsWindow()
		{
			if (tools == null || (tools != null && !tools.IsLoaded))
			{
				tools = new ToolsWindow();
				tools.Owner = this;

				tools.LeftOffset = 5;
				tools.TopOffset = 55 + toolBarTray1.Height + toolBarPropertys.Height;

				tools.Left = this.Left + tools.LeftOffset;
				tools.Top = this.Top + tools.TopOffset;
				tools.Show();
			}
		}

        private void ShowLayersDialog()
        {
            if (layers == null || (layers != null && !layers.IsLoaded))
            {
                layers = new LayerDialog(canvasManager.CurentDocument);
                layers.Owner = this;

                //layers.LeftOffset = 5;
                //layers.TopOffset = 44 + toolBarTray1.Height + toolBarPropertys.Height;

                //layers.Left = this.Left + tools.LeftOffset;
                //layers.Top = this.Top + tools.TopOffset;
                layers.Show();
            }
        }

		private void InitializeToolProperties()
		{
			double stroke = 1;
			try
			{
				stroke = double.Parse(comboPintThicknes.Items[comboPintThicknes.SelectedIndex].ToString());
			}
			catch { }
            Gencode.VECore.Tools.ToolProperty.StrokeThickness = stroke;
            Gencode.VECore.Tools.ToolProperty.Stroke = borderColorRect.Fill;
            Gencode.VECore.Tools.ToolProperty.Fill = fillColorRect.Fill;
		}

		private void RegisterTools()
		{
            Gencode.VECore.CanvasDocument.AddTool("line", new Gencode.VECore.Tools.LineTool());
            Gencode.VECore.CanvasDocument.AddTool("curve", new Gencode.VECore.Tools.CurveTool());
            Gencode.VECore.CanvasDocument.AddTool("grab", new Gencode.VECore.Tools.GrabTool());
            Gencode.VECore.CanvasDocument.AddTool("rectangle", new Gencode.VECore.Tools.RectangleTool());
            Gencode.VECore.CanvasDocument.AddTool("ellipse", new Gencode.VECore.Tools.EllipseTool());
            Gencode.VECore.CanvasDocument.AddTool("path", new Gencode.VECore.Tools.PolygonTool());
		}

        private void Beenden_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Tools_Click(object sender, RoutedEventArgs e)
        {
			ShowToolsWindow();
        }

        private void Layers_Click(object sender, RoutedEventArgs e)
        {
            ShowLayersDialog();
        }

        private void New_Click(object sender, RoutedEventArgs e)
        {
			

			WF.VecDraw.Dialog.NewVectorImage newdlg = new WF.VecDraw.Dialog.NewVectorImage();
			if (newdlg.ShowDialog() == true)
			{
				CreateNewCanvas(newdlg.ImageWidth, newdlg.ImageHeight);
			}

			/*
			drawingCanvas.Dispose();
			//canvasDock.
			//canvasDock.Content = canvas1;// .Children.Remove(canvas1);
			canvasDock.Children.Remove(drawingCanvas);

			drawingCanvas = new Gencode.VECGui.VECDrawingCanvas();// Gencode.VECGui.CADCanvas();

			drawingCanvas.Width = 800;
			drawingCanvas.Height = 600;

            //At 96 dpi
            //A4
			//canvas1.Width = 1122.24;
			//canvas1.Height = 793.92;

            //A3
            //canvas1.Width = 1589.76;
            //canvas1.Height = 1122.24;

            //A2
            //canvas1.Height = 1587.84;
            //canvas1.Width = 2245.44;

            //A1
            //canvas1.Width = 3178.56;
            //canvas1.Height = 2245.44;

			drawingCanvas.Margin = new Thickness(20, 20, 20, 20);
			drawingCanvas.Background = new SolidColorBrush(Colors.White);
			//drawingCanvas.BorderBrush = new SolidColorBrush(Colors.Black);
			//drawingCanvas.BorderThickness = new Thickness(1);

			//canvasDock.Content=canvas1;// .Children.Add(canvas1);
			canvasDock.Children.Add(drawingCanvas);
			
			//canvasDock.InvalidateVisual();

			statusPageSize.Text = (drawingCanvas.Width + " x " + drawingCanvas.Height);*/
        }

		private void CreateNewCanvas(double width, double height)
		{
            //throw new NotImplementedException();

            //canvasManager.Dispose();

            ////canvasDockGrid.Children.Remove(canvasManager);
            //canvasManager = new CanvasDocument();
            //canvasManager.Width = width;
            //canvasManager.Height = height;
            //canvasManager.Margin = new Thickness(50, 50, 50, 50);
            ////canvasManager.BorderBrush = new SolidColorBrush(Colors.Black);
            ////canvasManager.BorderThickness = new Thickness(1);
            ////canvasDockGrid.Children.Add(canvasManager);
            //statusPageSize.Text = (canvasManager.Width + " x " + canvasManager.Height);


            canvasManager.Dispose();

            //canvasDockGrid.Children.Remove(canvasManager);
            canvasManager.AddCanvas(width, height);
            canvasManager.Width = width;
            canvasManager.Height = height;
            //canvasManager.Margin = new Thickness(50, 50, 50, 50);
            //canvasManager.BorderBrush = new SolidColorBrush(Colors.Black);
            //canvasManager.BorderThickness = new Thickness(1);
            //canvasDockGrid.Children.Add(canvasManager);
            statusPageSize.Text = (canvasManager.Width + " x " + canvasManager.Height);



			RegisterTools();
		}

        /// <summary>
        /// Initialize helper objects from the DocToolkit Library.
        /// 
        /// Called from Form1_Load. Initialized all objects except
        /// PersistWindowState wich must be initialized in the
        /// form constructor.
        /// </summary>
        private void InitializeHelperObjects()
        {
            // DocManager

            //DocManagerData data = new DocManagerData();
            //data.FormOwner = this;
            //data.UpdateTitle = true;
            //data.FileDialogFilter = "DrawTools files (*.dtl)|*.dtl|All Files (*.*)|*.*";
            //data.NewDocName = "Untitled.dtl";
            //data.RegistryPath = registryPath;

            docManager = new FileManager(/*data*/this);
            //docManager.RegisterFileType("dtl", "dtlfile", "DrawTools File");

            // Subscribe to DocManager events.
            docManager.SaveFile += documentManager_SaveEvent;
            docManager.LoadFile += documentManager_LoadEvent;

            //// Make "inline subscription" using anonymous methods.
            //docManager.OpenEvent += delegate(object sender, OpenFileEventArgs e)
            //{
            //    // Update MRU List
            //    if (e.Succeeded)
            //        mruManager.Add(e.FileName);
            //    else
            //        mruManager.Remove(e.FileName);
            //};

            docManager.DocChangedEvent += delegate(object o, EventArgs e)
            {
                canvasManager.CurentDocument.Refresh();
                canvasManager.CurentDocument.ClearHistory();
            };

            docManager.ClearEvent += delegate(object o, EventArgs e)
            {
                if (canvasManager != null)
                {
                    canvasManager.CurentDocument.ClearLayers();
                    canvasManager.CurentDocument.ClearHistory();
                    canvasManager.CurentDocument.AddLayer();
                }
            };

            //docManager.NewDocument();

            //// DragDropManager
            //dragDropManager = new DragDropManager(this);
            //dragDropManager.FileDroppedEvent += delegate(object sender, FileDroppedEventArgs e)
            //{
            //    OpenDocument(e.FileArray.GetValue(0).ToString());
            //};

            //// MruManager
            //mruManager = new MruManager();
            //mruManager.Initialize(
            //    this,                              // owner form
            //    recentFilesToolStripMenuItem,      // Recent Files menu item
            //    fileToolStripMenuItem,            // parent
            //    registryPath);                     // Registry path to keep MRU list

            //mruManager.MruOpenEvent += delegate(object sender, MruFileOpenEventArgs e)
            //{
            //    OpenDocument(e.FileName);
            //};
        }

		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
            // Helper objects (DocManager and others)
            InitializeHelperObjects();

			if (Properties.Settings.Default.ToolDialogVisible)
				ShowToolsWindow();

            if (Properties.Settings.Default.LayerDialogVisible)
                ShowLayersDialog();

			for (int i = 1; i < 25; i++)
				comboPintThicknes.Items.Add(i);
			comboPintThicknes.SelectedIndex = 0;

			CreateNewCanvas(600, 400);
		}

		private void DockPanel_MouseMove(object sender, MouseEventArgs e)
		{
            Point p = new Point(Mouse.GetPosition(canvasManager).X, Mouse.GetPosition(canvasManager).Y);
            //canvasManager.TranslatePoint(p, canvasDockGrid);
			statusMousePos.Text = ((int)p.X).ToString() + ", " + ((int)p.Y).ToString();
		}

		private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
		{
			if (tools != null && tools.IsLoaded)
			{
				if (this.Top < tools.TopOffset)
					tools.TopOffset = 44 + toolBarTray1.Height + toolBarPropertys.Height;
				if (this.Left < tools.LeftOffset)
					tools.LeftOffset = 5;

				tools.Left = this.Left + tools.LeftOffset;
				tools.Top = this.Top + tools.TopOffset;
			}
		}

        /// <summary>
        /// Save document to stream supplied by DocManager
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void documentManager_SaveEvent(object sender, SerializationEventArgs e)
        {
            try
            {
                Gencode.VECore.Serialization.VecSerializer ser = new Gencode.VECore.Serialization.VecSerializer();
                ser.Layers = canvasManager.CurentDocument.Layers;
                ser.Height = canvasManager.CurentDocument.Height;
                ser.Width = canvasManager.CurentDocument.Width;

                e.Formatter.Serialize(e.SerializationStream, ser);
            }
            catch (ArgumentNullException ex)
            {
                HandleSaveException(ex, e);
            }
            catch (System.Runtime.Serialization.SerializationException ex)
            {
                HandleSaveException(ex, e);
            }
            catch (System.Security.SecurityException ex)
            {
                HandleSaveException(ex, e);
            }
        }

        /// <summary>
        /// Load document from the stream supplied by DocManager
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void documentManager_LoadEvent(object sender, SerializationEventArgs e)
        {
            try
            {
                Gencode.VECore.Serialization.VecSerializer ser = (Gencode.VECore.Serialization.VecSerializer)e.Formatter.Deserialize(e.SerializationStream);
                //create new canvas
                CreateNewCanvas(ser.Width, ser.Height);
                //initialy there is a default layer
                canvasManager.CurentDocument.ClearLayers();

                foreach (CanvasLayer layer in ser.Layers)
                {
                    canvasManager.CurentDocument.AddLayer(layer);
                }
            }
            catch (ArgumentNullException ex)
            {
                HandleLoadException(ex, e);
            }
            catch (System.Runtime.Serialization.SerializationException ex)
            {
                HandleLoadException(ex, e);
            }
            catch (System.Security.SecurityException ex)
            {
                HandleLoadException(ex, e);
            }
        }

        /// <summary>
        /// Handle exception from docManager_LoadEvent function
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="fileName"></param>
        private void HandleLoadException(Exception ex, SerializationEventArgs e)
        {
            MessageBox.Show(this,
                "Open File operation failed. File name: " + e.FileName + "\n" +
                "Reason: " + ex.Message,
                this.Title);

            e.Error = true;
        }

        /// <summary>
        /// Handle exception from docManager_SaveEvent function
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="fileName"></param>
        private void HandleSaveException(Exception ex, SerializationEventArgs e)
        {
            MessageBox.Show(this,
                "Save File operation failed. File name: " + e.FileName + "\n" +
                "Reason: " + ex.Message,
                this.Title);

            e.Error = true;
        }



		private void comboPintThicknes_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			double stroke = 1;
			try
			{
				stroke = double.Parse(comboPintThicknes.Items[comboPintThicknes.SelectedIndex].ToString());
			}
			catch { }

            Gencode.VECore.Tools.ToolProperty.StrokeThickness = stroke;

            try
            {
                var changeCmd = new Gencode.VECore.History.StateChangeCommand(canvasManager.CurentDocument.SelectedLayer.ShapeList);

                //change all selected objects
                bool change = false;
                foreach (Gencode.VECore.VectorShape.VECShape shape in canvasManager.CurentDocument.SelectedLayer.ShapeList.Selection)
                {
                    shape.StrokeThickness = Gencode.VECore.Tools.ToolProperty.StrokeThickness;
                    change = true;
                }

                //add changeCommand to history of changes
                if (change)
                {
                    changeCmd.NewState(canvasManager.CurentDocument.SelectedLayer.ShapeList);
                    canvasManager.CurentDocument.AddCommandToHistory(changeCmd);
                }
            }
            catch { }
		}

		private void FillColorButton_Click(object sender, RoutedEventArgs e)
		{
			//TODO:
			//Allways static window with eventhandler for changing color
			WF.VecDraw.Dialog.ColorDialog cpd = new WF.VecDraw.Dialog.ColorDialog();
			cpd.Owner = this;

			cpd.Top = this.Top + 95;
			cpd.Left = this.Left + 30;
			cpd.SelectedColor = ((SolidColorBrush)fillColorRect.Fill).Color;

			if (cpd.ShowDialog() == true)
			{
				fillColorRect.Fill = new SolidColorBrush(cpd.SelectedColor);
                Gencode.VECore.Tools.ToolProperty.Fill = fillColorRect.Fill;

                var changeCmd = new Gencode.VECore.History.StateChangeCommand(canvasManager.CurentDocument.SelectedLayer.ShapeList);

                //change all selected objects
                bool change = false;
                foreach (Gencode.VECore.VectorShape.VECShape shape in canvasManager.CurentDocument.SelectedLayer.ShapeList.Selection)
                {
                    shape.Fill = Gencode.VECore.Tools.ToolProperty.Fill;
                    change = true;
                }

                //add changeCommand to history of changes
                if (change)
                {
                    changeCmd.NewState(canvasManager.CurentDocument.SelectedLayer.ShapeList);
                    canvasManager.CurentDocument.AddCommandToHistory(changeCmd);
                }
			}

			//WPFColorPickerLib.ColorDialog dlg = new WPFColorPickerLib.ColorDialog();
			//dlg.Show();
		}

		private void borderColorButton_Click(object sender, RoutedEventArgs e)
		{
			//TODO:
			//Allways static window with eventhandler for changing color
			WF.VecDraw.Dialog.ColorDialog cpd = new WF.VecDraw.Dialog.ColorDialog();
			cpd.Owner = this;

			cpd.Top = this.Top + 95;
			cpd.Left = this.Left + 90;
			cpd.SelectedColor = ((SolidColorBrush)borderColorRect.Fill).Color;

			if (cpd.ShowDialog() == true)
			{
				borderColorRect.Fill = new SolidColorBrush(cpd.SelectedColor);
                Gencode.VECore.Tools.ToolProperty.Stroke = borderColorRect.Fill;

                var changeCmd = new Gencode.VECore.History.StateChangeCommand(canvasManager.CurentDocument.SelectedLayer.ShapeList);

                //change all selected objects
                bool change = false;
                foreach (Gencode.VECore.VectorShape.VECShape shape in canvasManager.CurentDocument.SelectedLayer.ShapeList.Selection)
                {
                    shape.Stroke = Gencode.VECore.Tools.ToolProperty.Stroke;
                    change = true;
                }

                //add changeCommand to history of changes
                if (change)
                {
                    changeCmd.NewState(canvasManager.CurentDocument.SelectedLayer.ShapeList);
                    canvasManager.CurentDocument.AddCommandToHistory(changeCmd);
                }
			}
		}

        private void CommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.Redo)
            {
                canvasManager.CurentDocument.Redo();
            }
            else if (e.Command == ApplicationCommands.Undo)
            {
                canvasManager.CurentDocument.Undo();
            }
            else if (e.Command == ApplicationCommands.Delete)
            {
                //MessageBox.Show("not jet implemented!");
                canvasManager.CurentDocument.RemoveSelection();
            }
            else if (e.Command == ApplicationCommands.SelectAll)
            {
                canvasManager.CurentDocument.SelectedLayer.ShapeList.SelectAll();
            }
            else if (e.Command == ApplicationCommands.Stop)
            {
                canvasManager.CurentDocument.SelectedLayer.ShapeList.UnselectAll();
            }
            else if (e.Command == WF.VecDraw.VecApp.VDCustomCommands.UnselectAll)
            {
                MessageBox.Show("not jet implemented!");
            }
            else if (e.Command == WF.VecDraw.VecApp.VDCustomCommands.ZoomIn)
            {
                canvasManager.Height += 5;
                canvasManager.Width += 5;
            }
            else if (e.Command == WF.VecDraw.VecApp.VDCustomCommands.ZoomOut)
            {
                canvasManager.Height -= 5;
                canvasManager.Width -= 5;
            }
        }

        private void CommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;//I am always returning true, based on this the menu item will enabled / disabled
        }

        private void ShowGrid_Click(object sender, RoutedEventArgs e)
        {
            if (CanvasDocument.ShowGrid)
            {
                CanvasDocument.ShowGrid = false;
                MenuItemShowGrid.IsChecked = false;
            }
            else
            {
                CanvasDocument.ShowGrid = true;
                MenuItemShowGrid.IsChecked = true;
            }
        }

        //TEST
        private void SaveAs_Click(object sender, RoutedEventArgs e)
        {
            docManager.SaveDocument(FileManager.SaveType.SaveAs);
        }

        private void Open_Click(object sender, RoutedEventArgs e)
        {
            docManager.OpenDocument("");
        }

        private void ToPoligon_Click(object sender, RoutedEventArgs e)
        {
            if (canvasManager.CurentDocument.SelectedLayer.ShapeList.SelectionCount == 1)
            {
                List<Gencode.VECore.VectorShape.VECShape> shapes = new List<Gencode.VECore.VectorShape.VECShape>();
                foreach (Gencode.VECore.VectorShape.VECShape s in canvasManager.CurentDocument.SelectedLayer.ShapeList.Selection)
                    shapes.Add(s);

                foreach (Gencode.VECore.VectorShape.VECShape s in shapes)
                {
                    var shape = s as Gencode.VECore.VectorShape.VECRectangle;
                    if (shape != null)
                    {
                        var polygon = Gencode.VECore.VectorShape.VECShape.ToPolygon(shape);
                        canvasManager.CurentDocument.SelectedLayer.Replace(shape, polygon);
                    }
                }
            }
        }
    }
}
